package com.lxy.controller.Rider;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.lxy.common.BaseContext;
import com.lxy.common.R;
import com.lxy.constant.CodeConstant;
import com.lxy.constant.JwtClaimsConstant;
import com.lxy.dto.*;
import com.lxy.entity.*;
import com.lxy.properties.JwtProperties;
import com.lxy.service.*;
import com.lxy.utils.JwtUtil;
import com.lxy.vo.OrdersAreAvailableVO;
import com.lxy.vo.OrdersAreTakenVO;
import com.lxy.vo.RiderLoginVO;
import com.lxy.vo.UserLoginVO;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/rider")
public class RiderController {
    @Autowired
    private RiderService riderService;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RiderPlaceService riderPlaceService;
    @Autowired
    private MailSender mailSender;
    @Autowired
    private BuyOrderService buyOrderService;
    @Autowired
    private SendOrderService sendOrderService;
    @Autowired
    private RiderAccountService riderAccountService;
    @Autowired
    public HistoryOrderService historyOrderService;
    @Autowired
    public HistorySendOrderService historySendOrderService;

    public static final String title="飞鸟跑腿APP";
    private String ak="wUO6QkgZ21Db6nOR1QdvbAzphr9omiSV";


    /**
     * 发送email
     */
    public void sendEmail(String email,String title,String text){
        //给用户发消息
        SimpleMailMessage mailMessage = new SimpleMailMessage(); //创建一个邮件信息
        System.out.println("当前时间" + new Date());
        mailMessage.setSubject(title);//邮件的主题
        mailMessage.setText(text);//邮件的内容
        mailMessage.setTo(email);//接收者的邮箱
        mailMessage.setFrom("3319725459@qq.com");//发送者的邮箱
        mailSender.send(mailMessage);//发送邮件
    }

    /**
     * 骑手登录
     */
    @ApiOperation("骑手登录")
    @PostMapping("/login")
    public R<RiderLoginVO> login(@RequestBody LoginDTO loginDTO){
        //判断账户是否存在
        LambdaQueryWrapper<Rider> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Rider::getAccount,loginDTO.getAccount());
        Rider rider = riderService.getOne(lambdaQueryWrapper);
        if(rider==null){
            //账户不存在
            return R.error("账户不存在，请先注册");
        }
        //判断密码是否正确
        String password = DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        if(!password.equals(rider.getPassword())){
            //密码错误
            return R.error("密码错误，请重试");
        }
        //判断账户是否被审核
        if(rider.getStatus()==0){
            return R.error("账户审核中");
        }
        if(rider.getBanded()==0){
            return R.error("账户被禁用，请联系管理员解封");
        }
        //登录成功，生成jwt令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.RIDER_ID, rider.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getRiderSecretKey(),
                jwtProperties.getRiderTtl(),
                claims);
        RiderLoginVO riderLoginVO=new RiderLoginVO();
        riderLoginVO.setRider(rider);
        riderLoginVO.setToken(token);
        return R.success(riderLoginVO);
    }



    /**
     * 骑手注册（登陆界面处）
     */
    @ApiOperation("骑手注册（登陆界面处）")
    @PostMapping("/registration")
    public R<String> registration(@RequestBody RiderRegistrationDTO riderRegistrationDTO){
        //先查找是否已经注册成为骑手
        LambdaQueryWrapper<Rider> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Rider::getEmail,riderRegistrationDTO.getEmail());
        Rider getByEmail = riderService.getOne(lambdaQueryWrapper);
        if(getByEmail!=null){
            return R.error("已经注册成为骑手，请勿重复注册");
        }
        //判断手机号是否注册
        lambdaQueryWrapper.clear();
        lambdaQueryWrapper.eq(Rider::getPhone,riderRegistrationDTO.getPhone());
        Rider getByPhone = riderService.getOne(lambdaQueryWrapper);
        if(getByPhone!=null){
            return R.error("该手机号已注册");
        }
        //判断账号名是否重复
        lambdaQueryWrapper.clear();
        lambdaQueryWrapper.eq(Rider::getAccount,riderRegistrationDTO.getAccount());
        Rider getByAccount = riderService.getOne(lambdaQueryWrapper);
        if(getByAccount!=null){
            return R.error("用户名重复");
        }
        //检验验证码
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String key=riderRegistrationDTO.getEmail()+ CodeConstant.RIDER_REGISTRATION;
        Integer Rcode =(Integer) valueOperations.get(key);
        if(!Rcode.equals(riderRegistrationDTO.getCode())){
            return R.error("验证码错误，请重试");
        }
        //验证码正确，删除缓存
        redisTemplate.delete(key);
        //创建rider数据
        Rider rider=new Rider();
        BeanUtils.copyProperties(riderRegistrationDTO,rider);
        String password = DigestUtils.md5DigestAsHex(riderRegistrationDTO.getPassword().getBytes());
        rider.setPassword(password);
        rider.setCreateTime(LocalDateTime.now());
        rider.setStatus(0);
        rider.setBanded(1);
        rider.setIsOk(0);
        rider.setIsSend(0);
        rider.setMonthAppraise(BigDecimal.valueOf(4));
        riderService.save(rider);
        //创建rider_place数据
        RiderPlace riderPlace=new RiderPlace();
        BeanUtils.copyProperties(riderRegistrationDTO,riderPlace);
        riderPlace.setRiderId(rider.getId());
        riderPlaceService.save(riderPlace);
        //发送邮件给用户
        String text="感谢您对本软件的支持："+rider.getName()+" 您的骑手申请已经提交，将在七个工作日内审核";
        sendEmail(rider.getEmail(),title,text);
        //创建riderAccount数据
        RiderAccount riderAccount=new RiderAccount();
        riderAccount.setRiderId(rider.getId());
        riderAccount.setMoney(BigDecimal.valueOf(0));
        riderAccount.setOrderNumber(0L);
        riderAccountService.save(riderAccount);
        return R.success("申请提交成功，将在七个工作日内审核");
    }

    /**
     * 忘记密码
     */
    @ApiOperation("忘记密码")
    @PostMapping("/forget")
    private R<String> forget(@RequestBody ForgetDTO forgetDTO){
        String email = forgetDTO.getEmail();
        //先判断
        Integer code = forgetDTO.getCode();
        //查找对应的rider数据
        LambdaQueryWrapper<Rider> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Rider::getEmail,email);
        Rider rider = riderService.getOne(lambdaQueryWrapper);
        //判断账号是否正常
        if(rider.getStatus()==0){
            return R.error("该账号还在审核中");
        }else if(rider.getBanded()==0){
            return R.error("账号被禁用");
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Integer Rcode = (Integer)valueOperations.get(email+CodeConstant.RIDER_FORGET);
        if(!Objects.equals(Rcode, code)){
            return R.error("验证码错误，请重试");
        }
        //验证码正确,删除redis缓存
        redisTemplate.delete(email+CodeConstant.RIDER_FORGET);
        //更新新密码
        String password = DigestUtils.md5DigestAsHex(forgetDTO.getPassword().getBytes());
        rider.setPassword(password);
        riderService.updateById(rider);
        return R.success("找回密码成功");
    }

    /**
     * 查看所有可接订单
     */
    @ApiOperation("查看所有可接订单")
    @GetMapping("/ordersAreAvailable")
    public R<OrdersAreAvailableVO> ordersAreAvailable(){
        //所有帮我买订单(在城市内)
        LambdaQueryWrapper<BuyOrder> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BuyOrder::getStatus,0);
        //找到骑手工作城市
        Long riderId = BaseContext.getCurrentId();
        LambdaQueryWrapper<RiderPlace> riderPlaceLambdaQueryWrapper=new LambdaQueryWrapper<>();
        riderPlaceLambdaQueryWrapper.eq(RiderPlace::getRiderId,riderId);
        RiderPlace riderPlace = riderPlaceService.getOne(riderPlaceLambdaQueryWrapper);
        String workCity = riderPlace.getWorkCity();
        //需要在一个城市内
        lambdaQueryWrapper.eq(BuyOrder::getCity,workCity);
        List<BuyOrder> buyOrderList = buyOrderService.list(lambdaQueryWrapper);
        //所有帮我送、帮我取订单
        LambdaQueryWrapper<SendOrder> lambdaQueryWrapper1=new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.eq(SendOrder::getStatus,0);
        lambdaQueryWrapper1.eq(SendOrder::getCity,workCity);
        List<SendOrder> sendOrderList = sendOrderService.list(lambdaQueryWrapper1);
        OrdersAreAvailableVO ordersAreAvailableVO=new OrdersAreAvailableVO();
        ordersAreAvailableVO.setBuyOrderList(buyOrderList);
        ordersAreAvailableVO.setSendOrderList(sendOrderList);
        return R.success(ordersAreAvailableVO);
    }

    /**
     * 接受订单
     */
    @ApiOperation("接受订单")
    @GetMapping("/acceptOrder")
    public R<String> acceptOrder(Integer type,Long id){
        //type=0 表示帮我买，1表示帮我送、取
        if(type==0){
            //帮我买
            BuyOrder buyOrder = buyOrderService.getById(id);
            //如果点击之前就被别的骑手抢了，会报错
            if(buyOrder.getStatus()==1){
                return R.error("您来晚了，该单已被接单");
            }
            //接单
            buyOrder.setRiderId(BaseContext.getCurrentId());
            buyOrder.setStatus(1);
            boolean isUpdate = buyOrderService.updateById(buyOrder);
            if(!isUpdate){
                return R.error("您的手速慢了，未抢到该单");
            }
            //成功接单
        }else{
            //帮我送、取
            SendOrder sendOrder = sendOrderService.getById(id);
            if(sendOrder.getStatus()==1){
                return R.error("您来晚了，该单已被接单");
            }
            sendOrder.setRiderId(BaseContext.getCurrentId());
            sendOrder.setStatus(1);
            boolean isUpdate = sendOrderService.updateById(sendOrder);
            if(!isUpdate){
                return R.error("您的手速慢了，未抢到该单");
            }
        }
        return R.success("成功接单");
    }


    /**
     * 完成订单
     * @param id 订单id
     * @param type 订单类型，0帮我买，1帮我送、取
     * @return
     */
    @ApiOperation("完成订单")
    @GetMapping("/completeOrder")
    public R completeOrder(Long id, Integer type,BigDecimal money){
        //修改riderAccount数据
        LambdaQueryWrapper<RiderAccount> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        Long riderId = BaseContext.getCurrentId();
        lambdaQueryWrapper.eq(RiderAccount::getRiderId,riderId);
        RiderAccount riderAccount = riderAccountService.getOne(lambdaQueryWrapper);
        riderAccount.setOrderNumber(riderAccount.getOrderNumber()+1);
        if(type==0){
            //帮我买
            //获取buyOrder数据
            BuyOrder buyOrder = buyOrderService.getById(id);
            //生成history_buy_order数据
            HistoryOrder historyOrder=new HistoryOrder();
            BeanUtils.copyProperties(buyOrder,historyOrder);
            historyOrder.setEndTime(LocalDateTime.now());
            historyOrder.setAmount(buyOrder.getDeliveryAmount().add(money));
            historyOrder.setId(null);
            historyOrder.setOrderId(buyOrder.getId());
            //如果用户不评分，默认是4分
            historyOrder.setRiderAppraise(4);
            historyOrderService.save(historyOrder);
            //删除buyOrder数据
            buyOrderService.removeById(buyOrder);
            //修改riderAccount数据
            riderAccount.setMoney(riderAccount.getMoney().add(historyOrder.getAmount()));
            riderAccountService.updateById(riderAccount);
        }else{
            //帮我送、取
            SendOrder sendOrder = sendOrderService.getById(id);
            HistorySendOrder historySendOrder=new HistorySendOrder();
            BeanUtils.copyProperties(sendOrder,historySendOrder);
            historySendOrder.setEndTime(LocalDateTime.now());
            historySendOrder.setId(null);
            historySendOrder.setOrderId(sendOrder.getId());
            historySendOrder.setRiderAppraise(4);
            historySendOrderService.save(historySendOrder);
            sendOrderService.removeById(sendOrder);
            riderAccount.setMoney(riderAccount.getMoney().add(historySendOrder.getAmount()));
            riderAccountService.updateById(riderAccount);
        }
        return R.success("已完成订单");
    }

    /**
     * 查看自己的历史订单
     * @return
     */
    @ApiOperation("查看自己的历史订单")
    @GetMapping("/ordersAreTaken")
    public R<OrdersAreTakenVO> ordersAreTaken(){
        Long riderId = BaseContext.getCurrentId();
        LambdaQueryWrapper<HistoryOrder> historyOrderLambdaQueryWrapper=new LambdaQueryWrapper<>();
        historyOrderLambdaQueryWrapper.eq(HistoryOrder::getRiderId,riderId);
        List<HistoryOrder> historyOrderList = historyOrderService.list(historyOrderLambdaQueryWrapper);
        LambdaQueryWrapper<HistorySendOrder> historySendOrderLambdaQueryWrapper=new LambdaQueryWrapper<>();
        historySendOrderLambdaQueryWrapper.eq(HistorySendOrder::getRiderId,riderId);
        List<HistorySendOrder> historySendOrderList = historySendOrderService.list(historySendOrderLambdaQueryWrapper);
        OrdersAreTakenVO ordersAreTakenVO=new OrdersAreTakenVO();
        ordersAreTakenVO.setHistoryOrderList(historyOrderList);
        ordersAreTakenVO.setHistorySendOrderList(historySendOrderList);
        return R.success(ordersAreTakenVO);
    }

    /**
     * 查看自己所有信息
     */
    @ApiOperation("查看自己所有信息")
    @GetMapping("/myInformation")
    public R<Rider> myInformation(){
        Long riderId = BaseContext.getCurrentId();
        Rider rider = riderService.getById(riderId);
        return R.success(rider);
    }

    /**
     * 修改个人信息
     */
    @ApiOperation("修改个人信息")
    @PostMapping("/updateInformation")
    public R<String> updateInformation(@RequestBody Rider rider){
        riderService.updateById(rider);
        return R.success("修改信息成功");
    }









}
